package com.wangsh.train.ques.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.wangsh.train.common.pojo.ApiResponse;
import com.wangsh.train.common.pojo.ApiResponseEnum;
import com.wangsh.train.common.service.BaseServiceImpl;
import com.wangsh.train.common.util.ConstatFinalUtil;
import com.wangsh.train.common.util.PageInfoUtil;
import com.wangsh.train.ques.pojo.AAsk;
import com.wangsh.train.ques.pojo.AAskEnum;
import com.wangsh.train.ques.pojo.AExamDesc;
import com.wangsh.train.ques.pojo.AExamDescEnum;
import com.wangsh.train.ques.service.IExamDbService;
import com.wangsh.train.ques.service.IExamOperService;
import com.wangsh.train.ques.service.IQuesDbService;
import com.wangsh.train.system.pojo.ASysPro;

/**
 * Service实现类(考试代码)
 * 
 * @author Wangsh
 */
@Service("examOperService")
public class ExamOperServiceImplay extends BaseServiceImpl implements IExamOperService
{
	@Resource
	private IExamDbService examDbService;
	@Resource
	private IQuesDbService quesDbService;
	
	/**
	 * 思路:
	 * 	根据id查询考试概要
	 * 	随机生成不同的技术类型对应的题库
	 */
	@Override
	public ApiResponse<Object> updateOneExamDescService(Map<String, Object> condMap)
	{
		ApiResponse<Object> apiResponse = new ApiResponse<Object>();
		Map<String, Object> extMap = new HashMap<String, Object>();
		/* 技术类型ids */
		String[] techIds = (String[]) condMap.get("techIds");
		/* 考试id */
		String relaId = condMap.get("relaId") + "";
		
		/* 查询考试详情 */
		extMap.clear();
		extMap.put("id", relaId);
		ApiResponse<AExamDesc> examApiResponse = this.examDbService.findOneExamDescService(extMap);
		AExamDesc examDesc = examApiResponse.getDataOneJava();
		if(examDesc.getExamType() == AExamDescEnum.EXAMTYPE_MACHINETEST.getStatus())
		{
			/* 全部是上机题 */
			examDesc = this.proccedMachineTest(examDesc,condMap);
		}else if(examDesc.getExamType() == AExamDescEnum.EXAMTYPE_INTERVIEW.getStatus())
		{
			/* 全部是问答题 */
			examDesc = this.proccedInterviewTest(examDesc,condMap);
		}else
		{
			/* 试卷型 */
			examDesc = proccedOtherNum(examDesc,condMap);
		}
		/* 更新结果 */
		apiResponse = this.examDbService.updateOneExamDescService(examDesc);
		return apiResponse;
	}

	/**
	 * 面试:(问的全部是问答题)
	 * @param examDesc
	 * @param condMap
	 * @return
	 */
	private AExamDesc proccedInterviewTest(AExamDesc examDesc, Map<String, Object> condMap)
	{
		/* 技术类型ids */
		String[] techIds = (String[]) condMap.get("techIds");
		/* 考试id */
		String relaId = condMap.get("relaId") + "";
		
		/* 设置数量 */
		ASysPro quesAskInterSysPro = (ASysPro) ConstatFinalUtil.SYS_PRO_MAP.get("ques_ask_inter_num");
		
		/* 随机数量
		 * 选择题共20道, 但是选择了四项技术,平均一样5道
		 *  */
		int askInterRanNum = Integer.valueOf(quesAskInterSysPro.getVals()) / techIds.length; 
		/* 说明至少每一个技术都要选择一个 */
		/* 存储技术类型的id */
		JSONObject examTechJSON = new JSONObject();
		Random random = new Random();
		if(askInterRanNum > 0 )
		{
			for (int i = 0; i < techIds.length; i++)
			{
				String idTemp = techIds[i];
				JSONObject dataTempJSON = new JSONObject();
				
				/* 生成选择题 */
				dataTempJSON.put("askInterRanNum", askInterRanNum);
				/* 只放考试的技术类型 */
				examTechJSON.put(idTemp, dataTempJSON);
			}
			
			/* 如果除不尽,随机选择一个技术,加上去 */
			if(Integer.valueOf(quesAskInterSysPro.getVals()) % techIds.length != 0)
			{
				/* 除不尽 */
				int randInt = random.nextInt(techIds.length);
				String idTemp = techIds[randInt];
				JSONObject examTechTempJSON = (JSONObject) examTechJSON.get(idTemp);
				int souNum = (int) examTechTempJSON.get("askInterRanNum");
				/* 还剩下多少个;把余数加上去 */
				souNum += Integer.valueOf(quesAskInterSysPro.getVals()) % techIds.length ;
				/* 加上结果 */
				examTechTempJSON.put("askInterRanNum", souNum);
			}
		}else
		{
			int yuShu = Integer.valueOf(quesAskInterSysPro.getVals()) % techIds.length  ; 
			for (int i = 0; i < yuShu; i++)
			{
				String idTemp = techIds[i];
				JSONObject dataTempJSON = new JSONObject();
				
				/* 生成选择题 */
				dataTempJSON.put("askInterRanNum", 1);
				/* 只放考试的技术类型 */
				examTechJSON.put(idTemp, dataTempJSON);
			}
		}
		
		/* 存储结果,更新 */
		examDesc.setExamTech(examTechJSON.toJSONString());
		return examDesc;
	}

	/**
	 * 机试(全部是编程题)
	 * @param examDesc
	 * @param condMap
	 * @return
	 */
	private AExamDesc proccedMachineTest(AExamDesc examDesc, Map<String, Object> condMap)
	{
		/* 技术类型ids */
		String[] techIds = (String[]) condMap.get("techIds");
		/* 考试id */
		String relaId = condMap.get("relaId") + "";
		
		/* 设置数量 */
		ASysPro quesProSysPro = (ASysPro) ConstatFinalUtil.SYS_PRO_MAP.get("ques_pro_num");
		
		/* 随机数量
		 * 选择题共20道, 但是选择了四项技术,平均一样5道
		 *  */
		int proRanNum = Integer.valueOf(quesProSysPro.getVals()) / techIds.length; 
		/* 存储技术类型的id */
		JSONObject examTechJSON = new JSONObject();
		Random random = new Random();
		if(proRanNum > 0 )
		{
			for (int i = 0; i < techIds.length; i++)
			{
				String idTemp = techIds[i];
				JSONObject dataTempJSON = new JSONObject();
				
				/* 生成选择题 */
				dataTempJSON.put("proRanNum", proRanNum);
				/* 只放考试的技术类型 */
				examTechJSON.put(idTemp, dataTempJSON);
			}
			
			/* 如果除不尽,随机选择一个技术,加上去 */
			if(Integer.valueOf(quesProSysPro.getVals()) % techIds.length != 0)
			{
				/* 除不尽 */
				int randInt = random.nextInt(techIds.length);
				String idTemp = techIds[randInt];
				JSONObject examTechTempJSON = (JSONObject) examTechJSON.get(idTemp);
				int souNum = (int) examTechTempJSON.get("proRanNum");
				/* 还剩下多少个;把余数加上去 */
				souNum += Integer.valueOf(quesProSysPro.getVals()) % techIds.length ;
				/* 加上结果 */
				examTechTempJSON.put("proRanNum", souNum);
			}
		}else
		{
			int yuShu = Integer.valueOf(quesProSysPro.getVals()) % techIds.length  ; 
			for (int i = 0; i < yuShu; i++)
			{
				String idTemp = techIds[i];
				JSONObject dataTempJSON = new JSONObject();
				
				/* 生成选择题 */
				dataTempJSON.put("proRanNum", 1);
				/* 只放考试的技术类型 */
				examTechJSON.put(idTemp, dataTempJSON);
			}
		}
		
		/* 存储结果,更新 */
		examDesc.setExamTech(examTechJSON.toJSONString());
		return examDesc;
	}

	/**
	 * 试卷数量(考试)
	 * @param condMap
	 * @param extMap
	 * @return
	 */
	private AExamDesc proccedOtherNum(AExamDesc examDesc,Map<String, Object> condMap)
	{
		/* 技术类型ids */
		String[] techIds = (String[]) condMap.get("techIds");
		/* 考试id */
		String relaId = condMap.get("relaId") + "";
		
		/* 设置数量 */
		ASysPro quesSelSysPro = (ASysPro) ConstatFinalUtil.SYS_PRO_MAP.get("ques_sel_num");
		ASysPro quesAskSysPro = (ASysPro) ConstatFinalUtil.SYS_PRO_MAP.get("ques_ask_num");
		//ASysPro quesProSysPro = (ASysPro) ConstatFinalUtil.SYS_PRO_MAP.get("ques_pro_num");
		ASysPro quesJudeSysPro = (ASysPro) ConstatFinalUtil.SYS_PRO_MAP.get("ques_judge_num");
		ASysPro quesMultiSysPro = (ASysPro) ConstatFinalUtil.SYS_PRO_MAP.get("ques_mutlSel_num");
		
		/* 随机数量
		 * 选择题共20道, 但是选择了四项技术,平均一样5道
		 *  */
		int selRanNum = Integer.valueOf(quesSelSysPro.getVals()) / techIds.length; 
		int askRanNum = Integer.valueOf(quesAskSysPro.getVals()) / techIds.length; 
		//int proRanNum = Integer.valueOf(quesProSysPro.getVals()) / techIds.length; 
		int judeRanNum = Integer.valueOf(quesJudeSysPro.getVals()) / techIds.length; 
		int multiSelRanNum = Integer.valueOf(quesMultiSysPro.getVals()) / techIds.length; 
		
		/* 存储技术类型的id */
		JSONObject examTechJSON = new JSONObject();
		for (int i = 0; i < techIds.length; i++)
		{
			String idTemp = techIds[i];
			JSONObject dataTempJSON = new JSONObject();
			
			/* 生成选择题 */
			dataTempJSON.put("selRanNum", selRanNum);
			/* 生成多选题 */
			dataTempJSON.put("multiSelRanNum", multiSelRanNum);
			/* 生成问答题 */
			dataTempJSON.put("askRanNum", askRanNum);
			/* 生成编程题 */
			//dataTempJSON.put("proRanNum", proRanNum);
			/* 生成判断题 */
			dataTempJSON.put("judeRanNum", judeRanNum);
			/* 只放考试的技术类型 */
			examTechJSON.put(idTemp, dataTempJSON);
		}
		
		Random random = new Random();
		/* 如果除不尽,随机选择一个技术,加上去 */
		if(Integer.valueOf(quesSelSysPro.getVals()) % techIds.length != 0)
		{
			/* 除不尽 */
			int randInt = random.nextInt(techIds.length);
			String idTemp = techIds[randInt];
			JSONObject examTechTempJSON = (JSONObject) examTechJSON.get(idTemp);
			int souNum = (int) examTechTempJSON.get("selRanNum");
			/* 还剩下多少个;把余数加上去 */
			souNum += Integer.valueOf(quesSelSysPro.getVals()) % techIds.length ;
			/* 加上结果 */
			examTechTempJSON.put("selRanNum", souNum);
		}
		if(Integer.valueOf(quesAskSysPro.getVals()) % techIds.length != 0)
		{
			/* 除不尽 */
			int randInt = random.nextInt(techIds.length);
			String idTemp = techIds[randInt];
			JSONObject examTechTempJSON = (JSONObject) examTechJSON.get(idTemp);
			int souNum = (int) examTechTempJSON.get("askRanNum");
			/* 还剩下多少个;把余数加上去 */
			souNum += Integer.valueOf(quesAskSysPro.getVals()) % techIds.length ;
			/* 加上结果 */
			examTechTempJSON.put("askRanNum", souNum);
		}
//		if(Integer.valueOf(quesProSysPro.getVals()) % techIds.length != 0)
//		{
//			/* 除不尽 */
//			int randInt = random.nextInt(techIds.length);
//			String idTemp = techIds[randInt];
//			JSONObject examTechTempJSON = (JSONObject) examTechJSON.get(idTemp);
//			int souNum = (int) examTechTempJSON.get("proRanNum");
//			/* 还剩下多少个;把余数加上去 */
//			souNum += Integer.valueOf(quesProSysPro.getVals()) % techIds.length ;
//			/* 加上结果 */
//			examTechTempJSON.put("proRanNum", souNum);
//		}
		if(Integer.valueOf(quesJudeSysPro.getVals()) % techIds.length != 0)
		{
			/* 除不尽 */
			int randInt = random.nextInt(techIds.length);
			String idTemp = techIds[randInt];
			JSONObject examTechTempJSON = (JSONObject) examTechJSON.get(idTemp);
			int souNum = (int) examTechTempJSON.get("judeRanNum");
			/* 还剩下多少个;把余数加上去 */
			souNum += Integer.valueOf(quesJudeSysPro.getVals()) % techIds.length ;
			/* 加上结果 */
			examTechTempJSON.put("judeRanNum", souNum);
		}
		if(Integer.valueOf(quesMultiSysPro.getVals()) % techIds.length != 0)
		{
			/* 除不尽 */
			int randInt = random.nextInt(techIds.length);
			String idTemp = techIds[randInt];
			JSONObject examTechTempJSON = (JSONObject) examTechJSON.get(idTemp);
			int souNum = (int) examTechTempJSON.get("multiSelRanNum");
			/* 还剩下多少个;把余数加上去 */
			souNum += Integer.valueOf(quesMultiSysPro.getVals()) % techIds.length ;
			/* 加上结果 */
			examTechTempJSON.put("multiSelRanNum", souNum);
		}
		
		/* 存储结果,更新 */
		examDesc.setExamTech(examTechJSON.toJSONString());
		return examDesc;
	}

	/**
	 * ~根据考试概要表里面的每个科目的数量
	 * ~到系统中随机抽题,并且放到List中
	 */
	@Override
	public ApiResponse<AExamDesc> proccedOneExamDescService(Map<String, Object> condMap)
	{
		String id = condMap.get("id") + "";
		ApiResponse<Object> apiResponse = new ApiResponse<Object>();
		Map<String, Object> extMap = new HashMap<String, Object>();
		
		/* 根据id查询考试概要 */
		extMap.clear();
		extMap.put("id", id);
		ApiResponse<AExamDesc> examApiResponse = this.examDbService.findOneExamDescService(extMap);
		AExamDesc examDesc = examApiResponse.getDataOneJava();
		/* 单选题结果 */
		List<AAsk> selResultList = new ArrayList<AAsk>();
		/* 多选题结果 */
		List<AAsk> multiSelResultList = new ArrayList<AAsk>();
		/* 问答题结果 */
		List<AAsk> askResultList = new ArrayList<AAsk>();
		/* 判断题结果 */
		List<AAsk> judeResultList = new ArrayList<AAsk>();
		/* 编程题结果 */
		List<AAsk> proResultList = new ArrayList<AAsk>();
		/* 面试题结果 */
		List<AAsk> interResultList = new ArrayList<AAsk>();
		/* 获取考试范围 */
		JSONObject examTechJSON = examDesc.getExamTechJSON();
		for (Iterator iterator = examTechJSON.entrySet().iterator(); iterator.hasNext();)
		{
			Entry<String, Object> temp = (Entry) iterator.next();
			
			/* 查询几次去抽题 */
			String tempKey = temp.getKey() ; 
			JSONObject tempVal = (JSONObject) temp.getValue() ; 
			ConstatFinalUtil.SYS_LOGGER.info("==查询考试概要==key:{},val:{}" ,tempKey,tempVal);
			/* 单选题 */
			int selRandNum = Integer.valueOf(tempVal.getIntValue("selRanNum")) ; 
			ApiResponse<AAsk> selAskApiResponse = findAskServiceUtil(tempKey, AAskEnum.ASKTYPE_SELECT.getStatus(),selRandNum);
			List<AAsk> selAskList = selAskApiResponse.getDataListJava();
			selResultList.addAll(selAskList);
			
			/* 多选题 */
			int multiSelRandNum = Integer.valueOf(tempVal.getIntValue("multiSelRanNum")) ; 
			ApiResponse<AAsk> multiSelAskApiResponse = findAskServiceUtil(tempKey, AAskEnum.ASKTYPE_MULSELECT.getStatus(),multiSelRandNum);
			List<AAsk> multiSelAskList = multiSelAskApiResponse.getDataListJava();
			multiSelResultList.addAll(multiSelAskList);
			
			/* 问答题 */
			int askSelRandNum = Integer.valueOf(tempVal.getIntValue("askRanNum")) ; 
			ApiResponse<AAsk> askSelAskApiResponse = findAskServiceUtil(tempKey, AAskEnum.ASKTYPE_QUES.getStatus(),askSelRandNum);
			List<AAsk> askSelAskList = askSelAskApiResponse.getDataListJava();
			askResultList.addAll(askSelAskList);
			
			/* 判断题 */
			int judeRanNum = Integer.valueOf(tempVal.getIntValue("judeRanNum")) ; 
			ApiResponse<AAsk> judeAskApiResponse = findAskServiceUtil(tempKey, AAskEnum.ASKTYPE_JUDGE.getStatus(),judeRanNum);
			List<AAsk> judeAskList = judeAskApiResponse.getDataListJava();
			judeResultList.addAll(judeAskList);
			
			/* 编程题题 */
			int proRandNum = Integer.valueOf(tempVal.getIntValue("proRanNum")) ; 
			ApiResponse<AAsk> proAskApiResponse = findAskServiceUtil(tempKey, AAskEnum.ASKTYPE_PROGRAM.getStatus(),proRandNum);
			List<AAsk> proAskList = proAskApiResponse.getDataListJava();
			proResultList.addAll(proAskList);
			
			/* 面试题题 */
			int askInterRanNum = Integer.valueOf(tempVal.getIntValue("askInterRanNum")) ; 
			ApiResponse<AAsk> proAsInterkApiResponse = findAskServiceUtil(tempKey, AAskEnum.ASKTYPE_QUES.getStatus(),askInterRanNum);
			List<AAsk> askInterList = proAsInterkApiResponse.getDataListJava();
			interResultList.addAll(askInterList);
		}
		
		/* 最终的结果 */
		List<AAsk> resultAskList = new ArrayList<AAsk>();
		/* 存储到最终结果 */
		Collections.shuffle(selResultList);
		resultAskList.addAll(selResultList);
		
		Collections.shuffle(multiSelResultList);
		resultAskList.addAll(multiSelResultList);
		
		Collections.shuffle(askResultList);
		resultAskList.addAll(askResultList);
		
		Collections.shuffle(judeResultList);
		resultAskList.addAll(judeResultList);
		
		Collections.shuffle(proResultList);
		resultAskList.addAll(proResultList);
		
		Collections.shuffle(interResultList);
		resultAskList.addAll(interResultList);
		
		examDesc.setSelResultList(selResultList);
		examDesc.setMultiSelResultList(multiSelResultList);
		examDesc.setAskResultList(askResultList);
		examDesc.setJudeResultList(judeResultList);
		examDesc.setProResultList(proResultList);
		examDesc.setInterResultList(interResultList);
		return examApiResponse;
	}

	/**
	 * 查询问题
	 * @param techId	技术id
	 * @param tempVal	技术数量
	 */
	private ApiResponse<AAsk> findAskServiceUtil(String techId,int askType ,int randNum)
	{
		Map<String, Object> extMap = new HashMap<String, Object>();
		ApiResponse<AAsk> apiResponse = new ApiResponse<AAsk>();
		/* 设置分页对象 */
		PageInfoUtil pageInfoUtil = new PageInfoUtil();
		
		/*==选择题==*/
		extMap.clear();
		extMap.put("techId", techId);
		extMap.put("askType", askType + "");
		extMap.put("status", AAskEnum.STATUS_AUDITYES.getStatus());
		extMap.put("orderBy", "randTimeAsc");
		if(randNum > 0 )
		{
			/* 分页对象 */
			pageInfoUtil.setPageSize(randNum);
			/* 查询问题的数量 */
			apiResponse = this.quesDbService.findCondListAskService(pageInfoUtil, extMap);
			List<AAsk> askList = apiResponse.getDataListJava() ;
			for (Iterator iterator = askList.iterator(); iterator.hasNext();)
			{
				AAsk ask = (AAsk) iterator.next();
				
				ask.setRandTime(new Date());
				/* 更新数据 */
				ApiResponse<Object> apiAskResponse = this.quesDbService.updateOneAskService(ask);
				ConstatFinalUtil.SYS_LOGGER.info("==更新结果:code:{},info:{}==",apiAskResponse.getCode() , apiResponse.getInfo());
			}
		}else
		{
			List<AAsk> AskList = Collections.EMPTY_LIST;
			Map<String, List<AAsk>> dataList = new HashMap<String, List<AAsk>>();
			/* 将结果放到JSON中 */
			dataList.put(ApiResponseEnum.NAME_LIST.getName(), AskList);
			apiResponse.setDataListJava(AskList);
			apiResponse.setDataList(dataList);
		}
		return apiResponse ; 
	}
}
